package com.wlcb.jpower.chat.reply;

import com.wlcb.jpower.chat.reply.handler.fixed.*;
import com.wlcb.jpower.chat.reply.handler.msgtype.ImageMsgHandler;
import com.wlcb.jpower.chat.reply.handler.msgtype.TextMsgHandler;
import com.wlcb.jpower.chat.reply.handler.msgtype.VoiceMsgHandler;
import com.wlcb.jpower.chat.service.wxuser.WxUserInfoService;
import com.wlcb.jpower.constant.ChatConstant;
import com.wlcb.jpower.im.cache.ImChatRecordCache;
import com.wlcb.jpower.im.cache.SessionCache;
import com.wlcb.jpower.im.model.DataPacket;
import com.wlcb.jpower.module.common.utils.Fc;
import com.wlcb.jpower.module.common.utils.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;

import java.util.HashMap;
import java.util.Map;

/**
 * @des: 回复
 * @author: fei
 * @time: 2021/2/4 17:09
 */
@Slf4j
public class ReplyContext {

    /**
     * 根据用户说的话找对应的处理器
     */
    private static final Map<String, ReplyHandler> FIXE_MESSAGE_MAP = new HashMap<>();

    /**
     * 根据消息类型执行
     */
    public static final Map<String, ReplyHandler> MESSAGE_TYPE_MAP = new HashMap<>();

    static {
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.NOSATISFIED.value, new SatisfactionHandler());
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.SATISFIED.value, new SatisfactionHandler());
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.ORDINARY.value, new SatisfactionHandler());
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.QUIT.value, new QuitReplyHandler());
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.QUIT_UNIT.value, new QuitUnitHandler());
        FIXE_MESSAGE_MAP.put(ChatConstant.ReplyEnum.QUIT_OPEN.value, new OpenUnitHandler());

        MESSAGE_TYPE_MAP.put(ChatConstant.MessageTypeEnum.TEXT.getType(), new TextMsgHandler());
        MESSAGE_TYPE_MAP.put(ChatConstant.MessageTypeEnum.IMAGE.getType(), new ImageMsgHandler());
        MESSAGE_TYPE_MAP.put(ChatConstant.MessageTypeEnum.VOICE.getType(), new VoiceMsgHandler());
    }

    private final WxMpXmlMessage wxMessage;
    private final DataPacket dataPacket;
    private final ImChatRecordCache cache;


    public static ReplyContext getInstance(DataPacket dataPacket, WxMpXmlMessage wxMessage, ImChatRecordCache cache) {
        return new ReplyContext(dataPacket, wxMessage, cache);
    }

    private ReplyContext(DataPacket dataPacket, WxMpXmlMessage wxMessage, ImChatRecordCache cache) {
        this.wxMessage = wxMessage;
        this.dataPacket = dataPacket;
        this.cache = cache;
    }

    /**
     * 先走FIXE_MESSAGE_MAP 再走ReplyChain
     *
     * @return
     */
    private ReplyEntity handler() {
        ReplyEntity replyEntity = fixedReply();
        if (Fc.isNull(replyEntity)) {
            return ReplyChain.getStart().handler(dataPacket, wxMessage);
        }
        return replyEntity;
    }

    /**
     * 直接FIXE_MESSAGE_MAP
     *
     * @return
     */
    private ReplyEntity fixedReply() {
        ReplyHandler receiveMessage = FIXE_MESSAGE_MAP.get(this.dataPacket.getContent());
        if (Fc.notNull(receiveMessage)) {
            return receiveMessage.handler(dataPacket, wxMessage);
        }
        return null;
    }

    /**
     * 获取reply实体
     */
    public ReplyEntity reply() throws WxErrorException {

        if (Fc.isNull(cache)) {
            SpringUtil.getBean(WxUserInfoService.class).collectUserInfo(dataPacket.getAppId(), wxMessage.getFromUser());
            return handler();
        } else {
            dataPacket.setDialogId(cache.getDialogId());
            //如果存在客服会话，需要继续执行固定回复
            return fixedReply();
        }
    }

    /**
     * 走了一圈没有返回结果 执行此方法转发到客服
     */
    public void forwardKefu() {
        if (Fc.notNull(cache)) {
            if (Fc.isNotBlank(cache.getCid()) && SessionCache.isSession(cache.getCid())) {
                SessionCache.write(cache.getCid(), dataPacket);
            }
            cache.setRecords(dataPacket);
            MESSAGE_TYPE_MAP.get(dataPacket.getType()).handler(dataPacket, wxMessage, cache);
        }
    }
}
